<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<title>Trace - zbus</title>
<script type="text/javascript" src="/js/jquery.js"></script>
<script type="text/javascript" src="/js/jquery-ui.js"></script>
<script type="text/javascript" src="/js/bootstrap.js"></script>
<script type="text/javascript" src="/js/base.js"></script>
<script type="text/javascript" src="/js/zbus.js"></script>
<link rel="stylesheet" href="/css/bootstrap.css" type="text/css">
<link rel="stylesheet" href="/css/base.css" type="text/css">

</head>
<body> 
<div class="header">

<nav class="navbar navbar-inverse navbar-static-top">
    <div class="container-fluid">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>  
            <a class="navbar-brand" href="/"> 
            	<img src="/img/logo.svg"></img> 
            	<span>ZBUS = MQ + RPC</span>
            </a> 
        </div>
        <div class="collapse navbar-collapse" id="navbar">
             <ul class="nav navbar-nav">
            	<li><a class="link" href="#">Trace</a></li>  
            	<li><a class="link" href="#">Topology</a></li> 
            </ul>
            <ul class="nav navbar-nav navbar-right">
                <li><a target="_blank" href="http://zbus.io/">Documentation</a></li>
                <li><a target="_blank" href="http://git.oschina.net/rushmore/zbus">Gitosc</a></li>
                <li><a target="_blank" href="http://github.com/rushmore/zbus">Github</a></li>
                <li class="hidden-xs"><p class="navbar-text"><span class="label label-success" id="version"></span></p></li>
            </ul> 
        </div>
    </div>
</nav>
</div>
 
<div class="nodes container-fluid">    
  
<div class="row">
    <div class="col-md-12">
        <span class="label label-primary">Servers</span>
    </div> 
    <div class="col-md-12">
        <table id="server-list"  class="table table-condensed table-bordered">
            <tbody>
            <tr> 
                <th style="width: 16%">Server Address 
                <div class="filter-box">
                	<input id="filter-all" type='checkbox' checked="checked">
                </div>
                </th> 
	            <th style="width: 8%">Version</th> 
                <th>Topics</th>
            </tr>  
        	</tbody>
        </table>
    </div> 
</div>   

<div class="row">
    <div class="col-md-12">
        <span class="label label-primary">Live Log</span>
    </div> 
    <div class="col-md-12">
    	<div id="trace-log">
    	</div> 
    </div> 
</div>   
 
</div>
 
 
<script type="text/javascript"> 


$(document).ready(function(){  
	
var trackBroker;
var tracingBrokerMap = {};  
var traceMessageCount = 50;
var serverSubTopicMap = {};

function calcFilter(){ 
	//compute serverList updated
	var filterServerList = [];
    $("#server-list input.server").each(function(data){
    	var checked = $(this).is(":checked");
    	if(checked){
    		filterServerList.push($(this).val());
    	} 
    });  
    trackBroker.filterServerList = filterServerList;  

    $("#server-list span.topic-badge").each(function(key, data){
    	$(this).siblings().each(function(key, data){
    		
    		var toDel = $(this).hasClass("topic-deactive");
    		var serverAddress = $(this).attr("address");
    		if(!serverAddress) return;
    		
    		var subTopics = serverSubTopicMap[serverAddress];
    		if(!subTopics){
    			subTopics = [];
    			serverSubTopicMap[serverAddress] = subTopics;
    		}
    		var topic = $(this).text(); 
    		
    		var idx = subTopics.indexOf(topic);
    		if(toDel){
    			if(idx >= 0){ 
    				subTopics.splice(idx, 1);
    			}
    		} else {
    			if(idx < 0){
    				subTopics.push(topic);
    			}
    		} 
    	});
    }); 
}

function updateTrackInfo(){  
	var filterServerList = trackBroker.filterServerList;
	
   	for(var serverAddress in trackBroker.serverInfoMap){ 
   		var serverInfo = trackBroker.serverInfoMap[serverAddress]; 
   		var broker = tracingBrokerMap[serverAddress]; 
       	
   		if(!trackBroker.inFilter(serverAddress)){
       		if(broker){
        		var msg = {};
        	    msg.cmd = Protocol.TRACE; 
        	    msg.flag = 0; //unsubscribe
        	    broker.sendMessage(msg); 
          	}  
       		continue;
   		} 
       	
   		subTopics = serverSubTopicMap[serverAddress]; 
       	if(!broker){
       		var broker = new Broker(serverAddress); 
       		broker.onMessage(function (msg) {
       			onTracingMessage(msg);
       	    });

       	    broker.connect(function (event) {
       	        var msg = {};
       	        msg.cmd = Protocol.TRACE; 
       	        if(subTopics){
       	        	msg.topic = subTopics.join();
       	        } 
       	        broker.sendMessage(msg);
       	    });
       	    tracingBrokerMap[serverAddress] = broker;
       	} else {
       		var msg = {};
    	    msg.cmd = Protocol.TRACE;  
    	    if(subTopics){
   	        	msg.topic = subTopics.join();
   	        }
    	    broker.sendMessage(msg); 
       	}  
   	}  
} 


$("#filter-all").change(function() {
	var checked = $(this).is(":checked");
	$("#server-list input.server").prop('checked', checked); 
	
	calcFilter();
	updateTrackInfo();
});  

$("#server-list").on("change", "input.server", function() {
	var checked = $(this).is(":checked");
    $(this).prop("checked", checked); 
    
    calcFilter();
    updateTrackInfo(); 
});

$("#server-list").on("click", "span.topic-list", function() {
	$(this).toggleClass("topic-deactive"); 
	
	calcFilter();
	updateTrackInfo();
});

$("#server-list").on("click", "span.topic-badge" ,function() { 
	$(this).toggleClass("badge-deactive"); 
	if($(this).hasClass("badge-deactive")){
		$(this).siblings().addClass("topic-deactive"); 
	} else {
		$(this).siblings().removeClass("topic-deactive");
	}
	calcFilter();
	updateTrackInfo(); 
});

$.get('/version',function(data){  
	$("#version").text(data); 
}); 
  
function serverTopicList(serverInfo){
	var topicMap = serverInfo.topicMap
	var res = "";
	var keys = Object.keys(topicMap);
	keys.sort();
	
	for(var i in keys){ 
		res += "<span address='" + serverInfo.serverAddress + "' class='topic-list topic label label-success'>" + keys[i] + "</span>";
	} 
   	return res;
}
   
function showServerTable(trackBroker){  
	$("#server-list").find("tr:gt(0)").remove();
	
	var serverInfoMap = trackBroker.serverInfoMap;
	for(var key in serverInfoMap){
		var serverInfo = serverInfoMap[key];
		var topicList = serverTopicList(serverInfo); 
		var checked ="checked=checked";
		var filterServerList = trackBroker.filterServerList;
		if(filterServerList && !filterServerList.includes(key)){
			checked = "";
		}
		
		$("#server-list").append(
			"<tr>\
				<td>\
					<a class='link' target='_blank' href='http://"+serverInfo.serverAddress + "'>" + serverInfo.serverAddress + "</a>\
					<div class='filter-box'>\
	            		<input class='server' type='checkbox' "+ checked +" value='"+serverInfo.serverAddress + "'>\
	            	</div>\
            	</td>\
				<td>" + serverInfo.serverVersion + "</td>\
				<td>\
	                <span class='topic topic-badge label label-success label-as-badge'>" + hashSize(serverInfo.topicMap) + "</span>" + topicList + "\
	           	</td>\
			</tr>"
		);    
	} 
}
 

function onTracingMessage(msg){
	if(msg.originUrl){ //return back to origin url
		msg.url = msg.originUrl;
		delete msg.originUrl;
		delete msg.status;
	}
	var str = httpEncodeString(msg);  
	if($("#trace-log pre").length > traceMessageCount){
		$('#trace-log pre:last-child').remove();
	}
	$("#trace-log").prepend("<pre>"+ new Date().format("yyyy-MM-dd hh:mm:ss.S") + "\n" + str+"</pre>");
}


$.getJSON('/info',function(serverInfo){   
	trackBroker = new TrackBroker(serverInfo.serverAddress); 
	trackBroker.onServerUpdated = function(serverAddress){  
		showServerTable(trackBroker);  
		updateTrackInfo();
	};
	
	trackBroker.connect();
	 
	for(var i in serverInfo.trackerList){
		var address = serverInfo.trackerList[i]; 
		$("#track-list").append(
			"<a class='link' target='_blank' href='http://" +address + "'>" + address + "</a>"
		);
	}  
});     

});


</script> 

</body>

</html>
